/*
 * Copyright Elasticsearch B.V. and contributors
 * SPDX-License-Identifier: Apache-2.0
 */

const { join } = require('path')
const { writeFile } = require('fs/promises')
const fetch = require('node-fetch')
const { rimraf } = require('rimraf')
const ora = require('ora')
const { convertRequests } = require('@elastic/request-converter')
const minimist = require('minimist')

const docsExamplesDir = join('docs', 'doc_examples')

const log = ora('Generating example snippets')

const failures = {}

async function getAlternativesReport (version = 'master') {
  const reportUrl = `https://raw.githubusercontent.com/elastic/built-docs/master/raw/en/elasticsearch/reference/${version}/alternatives_report.json`
  const response = await fetch(reportUrl)
  if (!response.ok) {
    log.fail(`unexpected response ${response.statusText}`)
    process.exit(1)
  }
  return await response.json()
}

async function makeSnippet (example) {
  const { source, digest } = example
  const fileName = `${digest}.asciidoc`
  const filePath = join(docsExamplesDir, fileName)

  try {
    const code = await convertRequests(source, 'javascript', {
      complete: false,
      printResponse: true
    })
    await writeFile(filePath, asciidocWrapper(code), 'utf8')
  } catch (err) {
    failures[digest] = err.message
  }
}

async function generate (version) {
  log.start()

  rimraf.sync(join(docsExamplesDir, '*'))

  log.text = `Downloading alternatives report for version ${version}`
  const examples = await getAlternativesReport(version)

  let counter = 1
  for (const example of examples) {
    log.text = `${counter++}/${examples.length}: ${example.digest}`

    // skip over bad request definitions
    if (example.source.startsWith('{') || example.source.endsWith('...')) {
      failures[example.digest] = 'Incomplete request syntax'
      continue
    }

    await makeSnippet(example)
  }
}

function asciidocWrapper (source) {
  return `// This file is autogenerated, DO NOT EDIT
// Use \`node scripts/generate-docs-examples.js\` to generate the docs examples

[source, js]
----
${source.trim()}
----
`
}

const options = minimist(process.argv.slice(2), {
  boolean: ['debug'],
  string: ['version'],
  default: {
    version: 'master'
  }
})

generate(options.version)
  .then(() => log.succeed('done!'))
  .catch(err => log.fail(err.message))
  .finally(() => {
    const keys = Object.keys(failures)
    if (keys.length > 0 && options.debug) {
      let message = 'Some examples failed to generate:\n\n'
      for (const key of keys) {
        message += `${key}: ${failures[key]}\n`
      }
      console.error(message)
    }
  })
